{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "## 1.4.2 神经网络的实现"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:33:46.543865800Z",
     "start_time": "2023-05-03T15:33:46.532847200Z"
    }
   },
   "outputs": [],
   "source": [
    "# 我们来实现一个具有一个隐藏层的神经网络\n",
    "import sys\n",
    "\n",
    "sys.path.append('..')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from common.layers import Affine, Sigmoid, SoftmaxWithLoss"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:33:47.686186800Z",
     "start_time": "2023-05-03T15:33:47.569613600Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [],
   "source": [
    "class TwoLayerNet:\n",
    "    def __init__(self, input_size, hidden_size, output_size):\n",
    "        I, H, O = input_size, hidden_size, output_size\n",
    "        # 初始化权重和偏置\n",
    "        W1 = 0.01 * np.random.randn(I, H)\n",
    "        b1 = np.zeros(H)\n",
    "        W2 = 0.01 * np.random.randn(H, O)\n",
    "        b2 = np.zeros(O)\n",
    "        # 生成层\n",
    "        self.layers = [\n",
    "            Affine(W1, b1),\n",
    "            Sigmoid(),\n",
    "            Affine(W2, b2)\n",
    "        ]\n",
    "        self.loss_layer = SoftmaxWithLoss()\n",
    "        # 将所有的权重和梯度整理到列表中\n",
    "        self.params, self.grads = [], []\n",
    "        for layer in self.layers:\n",
    "            self.params += layer.params\n",
    "            self.grads += layer.grads\n",
    "\n",
    "    # 我们为 TwoLayerNet 实现 3 个方法，即进行推理的 predict() 方法、正向传播的 forward() 方法和反向传播的 backward() 方法\n",
    "    def predict(self, x):\n",
    "        for layer in self.layers:\n",
    "            x = layer.forward(x)\n",
    "        return x\n",
    "\n",
    "    def forward(self, x, t):\n",
    "        score = self.predict(x)\n",
    "        loss = self.loss_layer.forward(score, t)\n",
    "        return loss\n",
    "\n",
    "    def backward(self, dout=1):\n",
    "        dout = self.loss_layer.backward(dout)\n",
    "        for layer in reversed(self.layers):\n",
    "            dout = layer.backward(dout)\n",
    "        return dout"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:38:03.603605600Z",
     "start_time": "2023-05-03T15:38:03.589583900Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "初始化程序接收 3 个参数。input_size 是输入层的神经元数，hidden_size 是隐藏层的神经元数，output_size 是输出层的神经元数。在内部实现中，首先用零向量（np.zeros()）初始化偏置，再用小的随机数（0.01 * np.random.randn()）初始化权重。通过将权重设成小的随机数，学习可以更容易地进行。接着，生成必要的层，并将它们整理到实例变量 layers 列表中。最后，将这个模型使用到的参数和梯度归纳在一起。\n",
    "\"\"\""
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 1.4.3 学习用的代码"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [],
   "source": [
    "import sys\n",
    "\n",
    "sys.path.append('..')"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:40:30.663934800Z",
     "start_time": "2023-05-03T15:40:30.646749400Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from common.optimizer import SGD\n",
    "from dataset import spiral\n",
    "import matplotlib.pyplot as plt"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:41:22.009782Z",
     "start_time": "2023-05-03T15:41:21.491997800Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [],
   "source": [
    "# 设定超参数\n",
    "max_epoch = 300\n",
    "batch_size = 30\n",
    "hidden_size = 10\n",
    "learning_rate = 1.0"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:41:45.251841800Z",
     "start_time": "2023-05-03T15:41:45.246844600Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [],
   "source": [
    "# 读入数据，生成模型和优化器\n",
    "x, t = spiral.load_data()\n",
    "model = TwoLayerNet(input_size=2, hidden_size=hidden_size, output_size=3)\n",
    "optimizer = SGD(lr=learning_rate)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:42:03.853628100Z",
     "start_time": "2023-05-03T15:42:03.837629200Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [],
   "source": [
    "# 学习用的变量\n",
    "data_size = len(x)\n",
    "max_iters = data_size // batch_size\n",
    "total_loss = 0\n",
    "loss_count = 0\n",
    "loss_list = []"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:43:43.895633700Z",
     "start_time": "2023-05-03T15:43:43.876635600Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "| epoch 1 | iter 10 / 10 | loss 1.10\n",
      "| epoch 2 | iter 10 / 10 | loss 1.12\n",
      "| epoch 3 | iter 10 / 10 | loss 1.10\n",
      "| epoch 4 | iter 10 / 10 | loss 1.08\n",
      "| epoch 5 | iter 10 / 10 | loss 1.18\n",
      "| epoch 6 | iter 10 / 10 | loss 1.22\n",
      "| epoch 7 | iter 10 / 10 | loss 1.24\n",
      "| epoch 8 | iter 10 / 10 | loss 1.13\n",
      "| epoch 9 | iter 10 / 10 | loss 1.12\n",
      "| epoch 10 | iter 10 / 10 | loss 1.20\n",
      "| epoch 11 | iter 10 / 10 | loss 1.22\n",
      "| epoch 12 | iter 10 / 10 | loss 1.22\n",
      "| epoch 13 | iter 10 / 10 | loss 1.10\n",
      "| epoch 14 | iter 10 / 10 | loss 1.12\n",
      "| epoch 15 | iter 10 / 10 | loss 1.24\n",
      "| epoch 16 | iter 10 / 10 | loss 1.32\n",
      "| epoch 17 | iter 10 / 10 | loss 1.16\n",
      "| epoch 18 | iter 10 / 10 | loss 1.10\n",
      "| epoch 19 | iter 10 / 10 | loss 1.13\n",
      "| epoch 20 | iter 10 / 10 | loss 1.12\n",
      "| epoch 21 | iter 10 / 10 | loss 1.06\n",
      "| epoch 22 | iter 10 / 10 | loss 1.42\n",
      "| epoch 23 | iter 10 / 10 | loss 1.11\n",
      "| epoch 24 | iter 10 / 10 | loss 1.17\n",
      "| epoch 25 | iter 10 / 10 | loss 1.06\n",
      "| epoch 26 | iter 10 / 10 | loss 1.24\n",
      "| epoch 27 | iter 10 / 10 | loss 1.11\n",
      "| epoch 28 | iter 10 / 10 | loss 1.11\n",
      "| epoch 29 | iter 10 / 10 | loss 1.11\n",
      "| epoch 30 | iter 10 / 10 | loss 1.13\n",
      "| epoch 31 | iter 10 / 10 | loss 1.13\n",
      "| epoch 32 | iter 10 / 10 | loss 1.24\n",
      "| epoch 33 | iter 10 / 10 | loss 1.20\n",
      "| epoch 34 | iter 10 / 10 | loss 1.08\n",
      "| epoch 35 | iter 10 / 10 | loss 1.15\n",
      "| epoch 36 | iter 10 / 10 | loss 1.10\n",
      "| epoch 37 | iter 10 / 10 | loss 1.14\n",
      "| epoch 38 | iter 10 / 10 | loss 1.13\n",
      "| epoch 39 | iter 10 / 10 | loss 1.15\n",
      "| epoch 40 | iter 10 / 10 | loss 1.34\n",
      "| epoch 41 | iter 10 / 10 | loss 1.16\n",
      "| epoch 42 | iter 10 / 10 | loss 1.13\n",
      "| epoch 43 | iter 10 / 10 | loss 1.20\n",
      "| epoch 44 | iter 10 / 10 | loss 1.12\n",
      "| epoch 45 | iter 10 / 10 | loss 1.10\n",
      "| epoch 46 | iter 10 / 10 | loss 1.10\n",
      "| epoch 47 | iter 10 / 10 | loss 1.10\n",
      "| epoch 48 | iter 10 / 10 | loss 1.20\n",
      "| epoch 49 | iter 10 / 10 | loss 1.29\n",
      "| epoch 50 | iter 10 / 10 | loss 1.18\n",
      "| epoch 51 | iter 10 / 10 | loss 1.12\n",
      "| epoch 52 | iter 10 / 10 | loss 1.14\n",
      "| epoch 53 | iter 10 / 10 | loss 1.12\n",
      "| epoch 54 | iter 10 / 10 | loss 1.17\n",
      "| epoch 55 | iter 10 / 10 | loss 1.23\n",
      "| epoch 56 | iter 10 / 10 | loss 1.12\n",
      "| epoch 57 | iter 10 / 10 | loss 1.10\n",
      "| epoch 58 | iter 10 / 10 | loss 1.17\n",
      "| epoch 59 | iter 10 / 10 | loss 1.26\n",
      "| epoch 60 | iter 10 / 10 | loss 1.09\n",
      "| epoch 61 | iter 10 / 10 | loss 1.14\n",
      "| epoch 62 | iter 10 / 10 | loss 1.16\n",
      "| epoch 63 | iter 10 / 10 | loss 1.10\n",
      "| epoch 64 | iter 10 / 10 | loss 1.12\n",
      "| epoch 65 | iter 10 / 10 | loss 1.08\n",
      "| epoch 66 | iter 10 / 10 | loss 1.15\n",
      "| epoch 67 | iter 10 / 10 | loss 1.07\n",
      "| epoch 68 | iter 10 / 10 | loss 1.17\n",
      "| epoch 69 | iter 10 / 10 | loss 1.09\n",
      "| epoch 70 | iter 10 / 10 | loss 1.18\n",
      "| epoch 71 | iter 10 / 10 | loss 1.10\n",
      "| epoch 72 | iter 10 / 10 | loss 1.12\n",
      "| epoch 73 | iter 10 / 10 | loss 1.11\n",
      "| epoch 74 | iter 10 / 10 | loss 1.17\n",
      "| epoch 75 | iter 10 / 10 | loss 1.17\n",
      "| epoch 76 | iter 10 / 10 | loss 1.22\n",
      "| epoch 77 | iter 10 / 10 | loss 1.22\n",
      "| epoch 78 | iter 10 / 10 | loss 1.06\n",
      "| epoch 79 | iter 10 / 10 | loss 1.10\n",
      "| epoch 80 | iter 10 / 10 | loss 1.12\n",
      "| epoch 81 | iter 10 / 10 | loss 1.21\n",
      "| epoch 82 | iter 10 / 10 | loss 1.15\n",
      "| epoch 83 | iter 10 / 10 | loss 1.07\n",
      "| epoch 84 | iter 10 / 10 | loss 1.15\n",
      "| epoch 85 | iter 10 / 10 | loss 1.08\n",
      "| epoch 86 | iter 10 / 10 | loss 1.10\n",
      "| epoch 87 | iter 10 / 10 | loss 1.12\n",
      "| epoch 88 | iter 10 / 10 | loss 1.10\n",
      "| epoch 89 | iter 10 / 10 | loss 1.08\n",
      "| epoch 90 | iter 10 / 10 | loss 1.14\n",
      "| epoch 91 | iter 10 / 10 | loss 1.08\n",
      "| epoch 92 | iter 10 / 10 | loss 1.11\n",
      "| epoch 93 | iter 10 / 10 | loss 1.10\n",
      "| epoch 94 | iter 10 / 10 | loss 1.11\n",
      "| epoch 95 | iter 10 / 10 | loss 1.15\n",
      "| epoch 96 | iter 10 / 10 | loss 1.13\n",
      "| epoch 97 | iter 10 / 10 | loss 1.10\n",
      "| epoch 98 | iter 10 / 10 | loss 1.07\n",
      "| epoch 99 | iter 10 / 10 | loss 1.17\n",
      "| epoch 100 | iter 10 / 10 | loss 1.21\n",
      "| epoch 101 | iter 10 / 10 | loss 1.15\n",
      "| epoch 102 | iter 10 / 10 | loss 1.11\n",
      "| epoch 103 | iter 10 / 10 | loss 1.10\n",
      "| epoch 104 | iter 10 / 10 | loss 1.10\n",
      "| epoch 105 | iter 10 / 10 | loss 1.18\n",
      "| epoch 106 | iter 10 / 10 | loss 1.09\n",
      "| epoch 107 | iter 10 / 10 | loss 1.11\n",
      "| epoch 108 | iter 10 / 10 | loss 1.15\n",
      "| epoch 109 | iter 10 / 10 | loss 1.28\n",
      "| epoch 110 | iter 10 / 10 | loss 1.14\n",
      "| epoch 111 | iter 10 / 10 | loss 1.10\n",
      "| epoch 112 | iter 10 / 10 | loss 1.10\n",
      "| epoch 113 | iter 10 / 10 | loss 1.10\n",
      "| epoch 114 | iter 10 / 10 | loss 1.08\n",
      "| epoch 115 | iter 10 / 10 | loss 1.08\n",
      "| epoch 116 | iter 10 / 10 | loss 1.13\n",
      "| epoch 117 | iter 10 / 10 | loss 1.12\n",
      "| epoch 118 | iter 10 / 10 | loss 1.08\n",
      "| epoch 119 | iter 10 / 10 | loss 1.09\n",
      "| epoch 120 | iter 10 / 10 | loss 1.11\n",
      "| epoch 121 | iter 10 / 10 | loss 1.06\n",
      "| epoch 122 | iter 10 / 10 | loss 1.13\n",
      "| epoch 123 | iter 10 / 10 | loss 1.12\n",
      "| epoch 124 | iter 10 / 10 | loss 1.05\n",
      "| epoch 125 | iter 10 / 10 | loss 1.05\n",
      "| epoch 126 | iter 10 / 10 | loss 1.10\n",
      "| epoch 127 | iter 10 / 10 | loss 1.06\n",
      "| epoch 128 | iter 10 / 10 | loss 1.06\n",
      "| epoch 129 | iter 10 / 10 | loss 1.06\n",
      "| epoch 130 | iter 10 / 10 | loss 1.07\n",
      "| epoch 131 | iter 10 / 10 | loss 1.05\n",
      "| epoch 132 | iter 10 / 10 | loss 1.04\n",
      "| epoch 133 | iter 10 / 10 | loss 1.10\n",
      "| epoch 134 | iter 10 / 10 | loss 1.04\n",
      "| epoch 135 | iter 10 / 10 | loss 1.02\n",
      "| epoch 136 | iter 10 / 10 | loss 1.09\n",
      "| epoch 137 | iter 10 / 10 | loss 1.08\n",
      "| epoch 138 | iter 10 / 10 | loss 0.98\n",
      "| epoch 139 | iter 10 / 10 | loss 1.18\n",
      "| epoch 140 | iter 10 / 10 | loss 0.98\n",
      "| epoch 141 | iter 10 / 10 | loss 1.03\n",
      "| epoch 142 | iter 10 / 10 | loss 1.05\n",
      "| epoch 143 | iter 10 / 10 | loss 1.04\n",
      "| epoch 144 | iter 10 / 10 | loss 1.06\n",
      "| epoch 145 | iter 10 / 10 | loss 1.01\n",
      "| epoch 146 | iter 10 / 10 | loss 1.07\n",
      "| epoch 147 | iter 10 / 10 | loss 1.04\n",
      "| epoch 148 | iter 10 / 10 | loss 1.01\n",
      "| epoch 149 | iter 10 / 10 | loss 1.00\n",
      "| epoch 150 | iter 10 / 10 | loss 1.02\n",
      "| epoch 151 | iter 10 / 10 | loss 1.04\n",
      "| epoch 152 | iter 10 / 10 | loss 0.96\n",
      "| epoch 153 | iter 10 / 10 | loss 1.01\n",
      "| epoch 154 | iter 10 / 10 | loss 1.00\n",
      "| epoch 155 | iter 10 / 10 | loss 1.01\n",
      "| epoch 156 | iter 10 / 10 | loss 0.98\n",
      "| epoch 157 | iter 10 / 10 | loss 1.11\n",
      "| epoch 158 | iter 10 / 10 | loss 1.04\n",
      "| epoch 159 | iter 10 / 10 | loss 0.95\n",
      "| epoch 160 | iter 10 / 10 | loss 0.93\n",
      "| epoch 161 | iter 10 / 10 | loss 1.03\n",
      "| epoch 162 | iter 10 / 10 | loss 0.97\n",
      "| epoch 163 | iter 10 / 10 | loss 1.07\n",
      "| epoch 164 | iter 10 / 10 | loss 0.96\n",
      "| epoch 165 | iter 10 / 10 | loss 0.91\n",
      "| epoch 166 | iter 10 / 10 | loss 0.95\n",
      "| epoch 167 | iter 10 / 10 | loss 0.96\n",
      "| epoch 168 | iter 10 / 10 | loss 0.91\n",
      "| epoch 169 | iter 10 / 10 | loss 0.95\n",
      "| epoch 170 | iter 10 / 10 | loss 0.99\n",
      "| epoch 171 | iter 10 / 10 | loss 0.87\n",
      "| epoch 172 | iter 10 / 10 | loss 1.01\n",
      "| epoch 173 | iter 10 / 10 | loss 0.83\n",
      "| epoch 174 | iter 10 / 10 | loss 1.05\n",
      "| epoch 175 | iter 10 / 10 | loss 0.89\n",
      "| epoch 176 | iter 10 / 10 | loss 0.90\n",
      "| epoch 177 | iter 10 / 10 | loss 0.94\n",
      "| epoch 178 | iter 10 / 10 | loss 0.90\n",
      "| epoch 179 | iter 10 / 10 | loss 0.92\n",
      "| epoch 180 | iter 10 / 10 | loss 0.85\n",
      "| epoch 181 | iter 10 / 10 | loss 0.83\n",
      "| epoch 182 | iter 10 / 10 | loss 0.90\n",
      "| epoch 183 | iter 10 / 10 | loss 0.89\n",
      "| epoch 184 | iter 10 / 10 | loss 0.88\n",
      "| epoch 185 | iter 10 / 10 | loss 0.87\n",
      "| epoch 186 | iter 10 / 10 | loss 0.86\n",
      "| epoch 187 | iter 10 / 10 | loss 0.82\n",
      "| epoch 188 | iter 10 / 10 | loss 0.81\n",
      "| epoch 189 | iter 10 / 10 | loss 0.84\n",
      "| epoch 190 | iter 10 / 10 | loss 0.98\n",
      "| epoch 191 | iter 10 / 10 | loss 1.04\n",
      "| epoch 192 | iter 10 / 10 | loss 0.93\n",
      "| epoch 193 | iter 10 / 10 | loss 0.84\n",
      "| epoch 194 | iter 10 / 10 | loss 0.88\n",
      "| epoch 195 | iter 10 / 10 | loss 0.73\n",
      "| epoch 196 | iter 10 / 10 | loss 0.89\n",
      "| epoch 197 | iter 10 / 10 | loss 0.89\n",
      "| epoch 198 | iter 10 / 10 | loss 0.87\n",
      "| epoch 199 | iter 10 / 10 | loss 0.74\n",
      "| epoch 200 | iter 10 / 10 | loss 0.90\n",
      "| epoch 201 | iter 10 / 10 | loss 0.82\n",
      "| epoch 202 | iter 10 / 10 | loss 0.91\n",
      "| epoch 203 | iter 10 / 10 | loss 0.94\n",
      "| epoch 204 | iter 10 / 10 | loss 0.84\n",
      "| epoch 205 | iter 10 / 10 | loss 0.84\n",
      "| epoch 206 | iter 10 / 10 | loss 1.02\n",
      "| epoch 207 | iter 10 / 10 | loss 0.88\n",
      "| epoch 208 | iter 10 / 10 | loss 0.87\n",
      "| epoch 209 | iter 10 / 10 | loss 0.70\n",
      "| epoch 210 | iter 10 / 10 | loss 0.90\n",
      "| epoch 211 | iter 10 / 10 | loss 0.77\n",
      "| epoch 212 | iter 10 / 10 | loss 0.77\n",
      "| epoch 213 | iter 10 / 10 | loss 0.74\n",
      "| epoch 214 | iter 10 / 10 | loss 0.86\n",
      "| epoch 215 | iter 10 / 10 | loss 0.79\n",
      "| epoch 216 | iter 10 / 10 | loss 0.90\n",
      "| epoch 217 | iter 10 / 10 | loss 0.74\n",
      "| epoch 218 | iter 10 / 10 | loss 0.86\n",
      "| epoch 219 | iter 10 / 10 | loss 0.67\n",
      "| epoch 220 | iter 10 / 10 | loss 0.84\n",
      "| epoch 221 | iter 10 / 10 | loss 0.69\n",
      "| epoch 222 | iter 10 / 10 | loss 0.70\n",
      "| epoch 223 | iter 10 / 10 | loss 0.77\n",
      "| epoch 224 | iter 10 / 10 | loss 0.88\n",
      "| epoch 225 | iter 10 / 10 | loss 0.79\n",
      "| epoch 226 | iter 10 / 10 | loss 0.68\n",
      "| epoch 227 | iter 10 / 10 | loss 0.72\n",
      "| epoch 228 | iter 10 / 10 | loss 0.65\n",
      "| epoch 229 | iter 10 / 10 | loss 0.70\n",
      "| epoch 230 | iter 10 / 10 | loss 0.77\n",
      "| epoch 231 | iter 10 / 10 | loss 0.79\n",
      "| epoch 232 | iter 10 / 10 | loss 0.70\n",
      "| epoch 233 | iter 10 / 10 | loss 0.80\n",
      "| epoch 234 | iter 10 / 10 | loss 0.86\n",
      "| epoch 235 | iter 10 / 10 | loss 0.73\n",
      "| epoch 236 | iter 10 / 10 | loss 0.72\n",
      "| epoch 237 | iter 10 / 10 | loss 0.75\n",
      "| epoch 238 | iter 10 / 10 | loss 0.83\n",
      "| epoch 239 | iter 10 / 10 | loss 0.64\n",
      "| epoch 240 | iter 10 / 10 | loss 0.80\n",
      "| epoch 241 | iter 10 / 10 | loss 0.71\n",
      "| epoch 242 | iter 10 / 10 | loss 0.59\n",
      "| epoch 243 | iter 10 / 10 | loss 0.69\n",
      "| epoch 244 | iter 10 / 10 | loss 0.79\n",
      "| epoch 245 | iter 10 / 10 | loss 0.68\n",
      "| epoch 246 | iter 10 / 10 | loss 0.80\n",
      "| epoch 247 | iter 10 / 10 | loss 0.82\n",
      "| epoch 248 | iter 10 / 10 | loss 0.85\n",
      "| epoch 249 | iter 10 / 10 | loss 0.63\n",
      "| epoch 250 | iter 10 / 10 | loss 0.84\n",
      "| epoch 251 | iter 10 / 10 | loss 0.79\n",
      "| epoch 252 | iter 10 / 10 | loss 0.77\n",
      "| epoch 253 | iter 10 / 10 | loss 0.78\n",
      "| epoch 254 | iter 10 / 10 | loss 0.63\n",
      "| epoch 255 | iter 10 / 10 | loss 0.74\n",
      "| epoch 256 | iter 10 / 10 | loss 0.74\n",
      "| epoch 257 | iter 10 / 10 | loss 0.70\n",
      "| epoch 258 | iter 10 / 10 | loss 0.86\n",
      "| epoch 259 | iter 10 / 10 | loss 0.79\n",
      "| epoch 260 | iter 10 / 10 | loss 0.93\n",
      "| epoch 261 | iter 10 / 10 | loss 0.85\n",
      "| epoch 262 | iter 10 / 10 | loss 0.71\n",
      "| epoch 263 | iter 10 / 10 | loss 0.77\n",
      "| epoch 264 | iter 10 / 10 | loss 0.76\n",
      "| epoch 265 | iter 10 / 10 | loss 0.71\n",
      "| epoch 266 | iter 10 / 10 | loss 0.83\n",
      "| epoch 267 | iter 10 / 10 | loss 0.80\n",
      "| epoch 268 | iter 10 / 10 | loss 0.88\n",
      "| epoch 269 | iter 10 / 10 | loss 0.63\n",
      "| epoch 270 | iter 10 / 10 | loss 0.80\n",
      "| epoch 271 | iter 10 / 10 | loss 0.72\n",
      "| epoch 272 | iter 10 / 10 | loss 0.76\n",
      "| epoch 273 | iter 10 / 10 | loss 1.12\n",
      "| epoch 274 | iter 10 / 10 | loss 0.83\n",
      "| epoch 275 | iter 10 / 10 | loss 0.66\n",
      "| epoch 276 | iter 10 / 10 | loss 0.66\n",
      "| epoch 277 | iter 10 / 10 | loss 0.69\n",
      "| epoch 278 | iter 10 / 10 | loss 0.67\n",
      "| epoch 279 | iter 10 / 10 | loss 0.75\n",
      "| epoch 280 | iter 10 / 10 | loss 0.72\n",
      "| epoch 281 | iter 10 / 10 | loss 0.75\n",
      "| epoch 282 | iter 10 / 10 | loss 0.83\n",
      "| epoch 283 | iter 10 / 10 | loss 0.75\n",
      "| epoch 284 | iter 10 / 10 | loss 0.82\n",
      "| epoch 285 | iter 10 / 10 | loss 0.71\n",
      "| epoch 286 | iter 10 / 10 | loss 0.77\n",
      "| epoch 287 | iter 10 / 10 | loss 0.75\n",
      "| epoch 288 | iter 10 / 10 | loss 0.71\n",
      "| epoch 289 | iter 10 / 10 | loss 0.83\n",
      "| epoch 290 | iter 10 / 10 | loss 0.58\n",
      "| epoch 291 | iter 10 / 10 | loss 0.62\n",
      "| epoch 292 | iter 10 / 10 | loss 0.84\n",
      "| epoch 293 | iter 10 / 10 | loss 0.90\n",
      "| epoch 294 | iter 10 / 10 | loss 0.76\n",
      "| epoch 295 | iter 10 / 10 | loss 0.76\n",
      "| epoch 296 | iter 10 / 10 | loss 0.91\n",
      "| epoch 297 | iter 10 / 10 | loss 0.74\n",
      "| epoch 298 | iter 10 / 10 | loss 0.79\n",
      "| epoch 299 | iter 10 / 10 | loss 0.90\n",
      "| epoch 300 | iter 10 / 10 | loss 0.69\n"
     ]
    }
   ],
   "source": [
    "for epoch in range(max_epoch):\n",
    "    # 打乱数据\n",
    "    idx = np.random.permutation(data_size)\n",
    "    x = x[idx]\n",
    "    t = t[idx]\n",
    "\n",
    "    for iters in range(max_iters):\n",
    "        batch_x = x[iters * batch_size:(iters + 1) * batch_size]\n",
    "        batch_t = t[iters * batch_size:(iters + 1) * batch_size]\n",
    "\n",
    "    # 计算梯度，更新参数\n",
    "    loss = model.forward(batch_x, batch_t)\n",
    "    model.backward()\n",
    "    optimizer.update(model.params, model.grads)\n",
    "\n",
    "    total_loss += loss\n",
    "    loss_count += 1\n",
    "\n",
    "    # 定期输出学习过程\n",
    "    if (iters + 1) % 10 == 0:\n",
    "        avg_loss = total_loss / loss_count\n",
    "        print('| epoch %d | iter %d / %d | loss %.2f'\n",
    "              % (epoch + 1, iters + 1, max_iters, avg_loss))\n",
    "        loss_list.append(avg_loss)\n",
    "        total_loss, loss_count = 0, 0"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:48:39.803111800Z",
     "start_time": "2023-05-03T15:48:39.751110600Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 1.4.4 Trainer类"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [],
   "source": [
    "from common.trainer import Trainer"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:51:53.291069200Z",
     "start_time": "2023-05-03T15:51:53.279069300Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "| epoch 1 |  iter 1 / 10 | time 0[s] | loss 0.91\n",
      "| epoch 2 |  iter 1 / 10 | time 0[s] | loss 0.74\n",
      "| epoch 3 |  iter 1 / 10 | time 0[s] | loss 0.76\n",
      "| epoch 4 |  iter 1 / 10 | time 0[s] | loss 0.77\n",
      "| epoch 5 |  iter 1 / 10 | time 0[s] | loss 0.75\n",
      "| epoch 6 |  iter 1 / 10 | time 0[s] | loss 0.76\n",
      "| epoch 7 |  iter 1 / 10 | time 0[s] | loss 0.72\n",
      "| epoch 8 |  iter 1 / 10 | time 0[s] | loss 0.77\n",
      "| epoch 9 |  iter 1 / 10 | time 0[s] | loss 0.75\n",
      "| epoch 10 |  iter 1 / 10 | time 0[s] | loss 0.75\n",
      "| epoch 11 |  iter 1 / 10 | time 0[s] | loss 0.76\n",
      "| epoch 12 |  iter 1 / 10 | time 0[s] | loss 0.73\n",
      "| epoch 13 |  iter 1 / 10 | time 0[s] | loss 0.74\n",
      "| epoch 14 |  iter 1 / 10 | time 0[s] | loss 0.78\n",
      "| epoch 15 |  iter 1 / 10 | time 0[s] | loss 0.70\n",
      "| epoch 16 |  iter 1 / 10 | time 0[s] | loss 0.71\n",
      "| epoch 17 |  iter 1 / 10 | time 0[s] | loss 0.75\n",
      "| epoch 18 |  iter 1 / 10 | time 0[s] | loss 0.76\n",
      "| epoch 19 |  iter 1 / 10 | time 0[s] | loss 0.70\n",
      "| epoch 20 |  iter 1 / 10 | time 0[s] | loss 0.73\n",
      "| epoch 21 |  iter 1 / 10 | time 0[s] | loss 0.72\n",
      "| epoch 22 |  iter 1 / 10 | time 0[s] | loss 0.71\n",
      "| epoch 23 |  iter 1 / 10 | time 0[s] | loss 0.74\n",
      "| epoch 24 |  iter 1 / 10 | time 0[s] | loss 0.71\n",
      "| epoch 25 |  iter 1 / 10 | time 0[s] | loss 0.75\n",
      "| epoch 26 |  iter 1 / 10 | time 0[s] | loss 0.73\n",
      "| epoch 27 |  iter 1 / 10 | time 0[s] | loss 0.72\n",
      "| epoch 28 |  iter 1 / 10 | time 0[s] | loss 0.72\n",
      "| epoch 29 |  iter 1 / 10 | time 0[s] | loss 0.71\n",
      "| epoch 30 |  iter 1 / 10 | time 0[s] | loss 0.73\n",
      "| epoch 31 |  iter 1 / 10 | time 0[s] | loss 0.72\n",
      "| epoch 32 |  iter 1 / 10 | time 0[s] | loss 0.72\n",
      "| epoch 33 |  iter 1 / 10 | time 0[s] | loss 0.67\n",
      "| epoch 34 |  iter 1 / 10 | time 0[s] | loss 0.72\n",
      "| epoch 35 |  iter 1 / 10 | time 0[s] | loss 0.68\n",
      "| epoch 36 |  iter 1 / 10 | time 0[s] | loss 0.69\n",
      "| epoch 37 |  iter 1 / 10 | time 0[s] | loss 0.67\n",
      "| epoch 38 |  iter 1 / 10 | time 0[s] | loss 0.68\n",
      "| epoch 39 |  iter 1 / 10 | time 0[s] | loss 0.69\n",
      "| epoch 40 |  iter 1 / 10 | time 0[s] | loss 0.69\n",
      "| epoch 41 |  iter 1 / 10 | time 0[s] | loss 0.65\n",
      "| epoch 42 |  iter 1 / 10 | time 0[s] | loss 0.67\n",
      "| epoch 43 |  iter 1 / 10 | time 0[s] | loss 0.68\n",
      "| epoch 44 |  iter 1 / 10 | time 0[s] | loss 0.67\n",
      "| epoch 45 |  iter 1 / 10 | time 0[s] | loss 0.64\n",
      "| epoch 46 |  iter 1 / 10 | time 0[s] | loss 0.64\n",
      "| epoch 47 |  iter 1 / 10 | time 0[s] | loss 0.64\n",
      "| epoch 48 |  iter 1 / 10 | time 0[s] | loss 0.65\n",
      "| epoch 49 |  iter 1 / 10 | time 0[s] | loss 0.62\n",
      "| epoch 50 |  iter 1 / 10 | time 0[s] | loss 0.64\n",
      "| epoch 51 |  iter 1 / 10 | time 0[s] | loss 0.61\n",
      "| epoch 52 |  iter 1 / 10 | time 0[s] | loss 0.61\n",
      "| epoch 53 |  iter 1 / 10 | time 0[s] | loss 0.61\n",
      "| epoch 54 |  iter 1 / 10 | time 0[s] | loss 0.59\n",
      "| epoch 55 |  iter 1 / 10 | time 0[s] | loss 0.60\n",
      "| epoch 56 |  iter 1 / 10 | time 0[s] | loss 0.59\n",
      "| epoch 57 |  iter 1 / 10 | time 0[s] | loss 0.59\n",
      "| epoch 58 |  iter 1 / 10 | time 0[s] | loss 0.56\n",
      "| epoch 59 |  iter 1 / 10 | time 0[s] | loss 0.56\n",
      "| epoch 60 |  iter 1 / 10 | time 0[s] | loss 0.54\n",
      "| epoch 61 |  iter 1 / 10 | time 0[s] | loss 0.55\n",
      "| epoch 62 |  iter 1 / 10 | time 0[s] | loss 0.53\n",
      "| epoch 63 |  iter 1 / 10 | time 0[s] | loss 0.52\n",
      "| epoch 64 |  iter 1 / 10 | time 0[s] | loss 0.51\n",
      "| epoch 65 |  iter 1 / 10 | time 0[s] | loss 0.49\n",
      "| epoch 66 |  iter 1 / 10 | time 0[s] | loss 0.51\n",
      "| epoch 67 |  iter 1 / 10 | time 0[s] | loss 0.48\n",
      "| epoch 68 |  iter 1 / 10 | time 0[s] | loss 0.46\n",
      "| epoch 69 |  iter 1 / 10 | time 0[s] | loss 0.46\n",
      "| epoch 70 |  iter 1 / 10 | time 0[s] | loss 0.46\n",
      "| epoch 71 |  iter 1 / 10 | time 0[s] | loss 0.42\n",
      "| epoch 72 |  iter 1 / 10 | time 0[s] | loss 0.44\n",
      "| epoch 73 |  iter 1 / 10 | time 0[s] | loss 0.43\n",
      "| epoch 74 |  iter 1 / 10 | time 0[s] | loss 0.40\n",
      "| epoch 75 |  iter 1 / 10 | time 0[s] | loss 0.43\n",
      "| epoch 76 |  iter 1 / 10 | time 0[s] | loss 0.40\n",
      "| epoch 77 |  iter 1 / 10 | time 0[s] | loss 0.38\n",
      "| epoch 78 |  iter 1 / 10 | time 0[s] | loss 0.37\n",
      "| epoch 79 |  iter 1 / 10 | time 0[s] | loss 0.38\n",
      "| epoch 80 |  iter 1 / 10 | time 0[s] | loss 0.36\n",
      "| epoch 81 |  iter 1 / 10 | time 0[s] | loss 0.35\n",
      "| epoch 82 |  iter 1 / 10 | time 0[s] | loss 0.35\n",
      "| epoch 83 |  iter 1 / 10 | time 0[s] | loss 0.36\n",
      "| epoch 84 |  iter 1 / 10 | time 0[s] | loss 0.35\n",
      "| epoch 85 |  iter 1 / 10 | time 0[s] | loss 0.33\n",
      "| epoch 86 |  iter 1 / 10 | time 0[s] | loss 0.34\n",
      "| epoch 87 |  iter 1 / 10 | time 0[s] | loss 0.32\n",
      "| epoch 88 |  iter 1 / 10 | time 0[s] | loss 0.32\n",
      "| epoch 89 |  iter 1 / 10 | time 0[s] | loss 0.31\n",
      "| epoch 90 |  iter 1 / 10 | time 0[s] | loss 0.30\n",
      "| epoch 91 |  iter 1 / 10 | time 0[s] | loss 0.31\n",
      "| epoch 92 |  iter 1 / 10 | time 0[s] | loss 0.30\n",
      "| epoch 93 |  iter 1 / 10 | time 0[s] | loss 0.28\n",
      "| epoch 94 |  iter 1 / 10 | time 0[s] | loss 0.30\n",
      "| epoch 95 |  iter 1 / 10 | time 0[s] | loss 0.28\n",
      "| epoch 96 |  iter 1 / 10 | time 0[s] | loss 0.28\n",
      "| epoch 97 |  iter 1 / 10 | time 0[s] | loss 0.28\n",
      "| epoch 98 |  iter 1 / 10 | time 0[s] | loss 0.27\n",
      "| epoch 99 |  iter 1 / 10 | time 0[s] | loss 0.28\n",
      "| epoch 100 |  iter 1 / 10 | time 0[s] | loss 0.26\n",
      "| epoch 101 |  iter 1 / 10 | time 0[s] | loss 0.27\n",
      "| epoch 102 |  iter 1 / 10 | time 0[s] | loss 0.25\n",
      "| epoch 103 |  iter 1 / 10 | time 0[s] | loss 0.26\n",
      "| epoch 104 |  iter 1 / 10 | time 0[s] | loss 0.25\n",
      "| epoch 105 |  iter 1 / 10 | time 0[s] | loss 0.27\n",
      "| epoch 106 |  iter 1 / 10 | time 0[s] | loss 0.23\n",
      "| epoch 107 |  iter 1 / 10 | time 0[s] | loss 0.25\n",
      "| epoch 108 |  iter 1 / 10 | time 0[s] | loss 0.24\n",
      "| epoch 109 |  iter 1 / 10 | time 0[s] | loss 0.24\n",
      "| epoch 110 |  iter 1 / 10 | time 0[s] | loss 0.24\n",
      "| epoch 111 |  iter 1 / 10 | time 0[s] | loss 0.25\n",
      "| epoch 112 |  iter 1 / 10 | time 0[s] | loss 0.23\n",
      "| epoch 113 |  iter 1 / 10 | time 0[s] | loss 0.23\n",
      "| epoch 114 |  iter 1 / 10 | time 0[s] | loss 0.22\n",
      "| epoch 115 |  iter 1 / 10 | time 0[s] | loss 0.21\n",
      "| epoch 116 |  iter 1 / 10 | time 0[s] | loss 0.21\n",
      "| epoch 117 |  iter 1 / 10 | time 0[s] | loss 0.23\n",
      "| epoch 118 |  iter 1 / 10 | time 0[s] | loss 0.22\n",
      "| epoch 119 |  iter 1 / 10 | time 0[s] | loss 0.21\n",
      "| epoch 120 |  iter 1 / 10 | time 0[s] | loss 0.21\n",
      "| epoch 121 |  iter 1 / 10 | time 0[s] | loss 0.19\n",
      "| epoch 122 |  iter 1 / 10 | time 0[s] | loss 0.22\n",
      "| epoch 123 |  iter 1 / 10 | time 0[s] | loss 0.19\n",
      "| epoch 124 |  iter 1 / 10 | time 0[s] | loss 0.20\n",
      "| epoch 125 |  iter 1 / 10 | time 0[s] | loss 0.19\n",
      "| epoch 126 |  iter 1 / 10 | time 0[s] | loss 0.20\n",
      "| epoch 127 |  iter 1 / 10 | time 0[s] | loss 0.20\n",
      "| epoch 128 |  iter 1 / 10 | time 0[s] | loss 0.21\n",
      "| epoch 129 |  iter 1 / 10 | time 0[s] | loss 0.20\n",
      "| epoch 130 |  iter 1 / 10 | time 0[s] | loss 0.20\n",
      "| epoch 131 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 132 |  iter 1 / 10 | time 0[s] | loss 0.19\n",
      "| epoch 133 |  iter 1 / 10 | time 0[s] | loss 0.20\n",
      "| epoch 134 |  iter 1 / 10 | time 0[s] | loss 0.19\n",
      "| epoch 135 |  iter 1 / 10 | time 0[s] | loss 0.19\n",
      "| epoch 136 |  iter 1 / 10 | time 0[s] | loss 0.19\n",
      "| epoch 137 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 138 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 139 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 140 |  iter 1 / 10 | time 0[s] | loss 0.19\n",
      "| epoch 141 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 142 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 143 |  iter 1 / 10 | time 0[s] | loss 0.17\n",
      "| epoch 144 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 145 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 146 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 147 |  iter 1 / 10 | time 0[s] | loss 0.17\n",
      "| epoch 148 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 149 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 150 |  iter 1 / 10 | time 0[s] | loss 0.17\n",
      "| epoch 151 |  iter 1 / 10 | time 0[s] | loss 0.17\n",
      "| epoch 152 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 153 |  iter 1 / 10 | time 0[s] | loss 0.17\n",
      "| epoch 154 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 155 |  iter 1 / 10 | time 0[s] | loss 0.18\n",
      "| epoch 156 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 157 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 158 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 159 |  iter 1 / 10 | time 0[s] | loss 0.17\n",
      "| epoch 160 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 161 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 162 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 163 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 164 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 165 |  iter 1 / 10 | time 0[s] | loss 0.16\n",
      "| epoch 166 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 167 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 168 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 169 |  iter 1 / 10 | time 0[s] | loss 0.17\n",
      "| epoch 170 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 171 |  iter 1 / 10 | time 0[s] | loss 0.17\n",
      "| epoch 172 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 173 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 174 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 175 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 176 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 177 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 178 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 179 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 180 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 181 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 182 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 183 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 184 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 185 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 186 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 187 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 188 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 189 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 190 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 191 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 192 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 193 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 194 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 195 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 196 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 197 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 198 |  iter 1 / 10 | time 0[s] | loss 0.15\n",
      "| epoch 199 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 200 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 201 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 202 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 203 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 204 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 205 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 206 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 207 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 208 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 209 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 210 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 211 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 212 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 213 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 214 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 215 |  iter 1 / 10 | time 0[s] | loss 0.14\n",
      "| epoch 216 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 217 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 218 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 219 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 220 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 221 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 222 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 223 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 224 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 225 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 226 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 227 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 228 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 229 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 230 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 231 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 232 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 233 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 234 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 235 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 236 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 237 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 238 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 239 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 240 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 241 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 242 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 243 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 244 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 245 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 246 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 247 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 248 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 249 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 250 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 251 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 252 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 253 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 254 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 255 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 256 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 257 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 258 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 259 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 260 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 261 |  iter 1 / 10 | time 0[s] | loss 0.09\n",
      "| epoch 262 |  iter 1 / 10 | time 0[s] | loss 0.13\n",
      "| epoch 263 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 264 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 265 |  iter 1 / 10 | time 0[s] | loss 0.12\n",
      "| epoch 266 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 267 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 268 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 269 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 270 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 271 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 272 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 273 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 274 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 275 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 276 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 277 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 278 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 279 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 280 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 281 |  iter 1 / 10 | time 0[s] | loss 0.09\n",
      "| epoch 282 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 283 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 284 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 285 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 286 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 287 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 288 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 289 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 290 |  iter 1 / 10 | time 0[s] | loss 0.11\n",
      "| epoch 291 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 292 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 293 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 294 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 295 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 296 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 297 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 298 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 299 |  iter 1 / 10 | time 0[s] | loss 0.10\n",
      "| epoch 300 |  iter 1 / 10 | time 0[s] | loss 0.10\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 640x480 with 1 Axes>",
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "trainer = Trainer(model, optimizer)\n",
    "trainer.fit(x, t, max_epoch, batch_size, eval_interval=10)\n",
    "trainer.plot()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-05-03T15:51:58.476275Z",
     "start_time": "2023-05-03T15:51:58.111274500Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
